﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using VulnDBExplorer.Services;

namespace Luna.Framework {
	public interface IActionManager {
		string Name { get; set; }

		IList<IActionable> Actions { get; set; }

		IActionableWorkingSet WorkingSet { get; }
	}

	public interface IActionable: IContextAwareObject {
		IProgressMonitor ProgressMonitor { get; } 
		string Name { get; set; }
		void execute(object sender, ActionExecutionArgs args);
		void abort(object stateInfo);

		event EventHandler<ActionExecutionArgs> Execute;
		event EventHandler Executed;
		event EventHandler<ActionExecuteErrorArgs> Error;
	}

	public interface IActionableWorkingSet {
		IEnumerable<IActionable> WorkingActions { get; }

		void addAction(IActionable actionable);

		void removeAction(IActionable actionable);
	}

	public interface IVisualActionable: IActionable {
		string Text { get; set; }
		Image Image { get; set; }
		bool Enabled { get; set; }

		/// <summary>
		/// Return a reference this action image. So that, changing image of an action will automatically
		/// change all assocciated object.
		/// </summary>
		/// <returns></returns>
		Image getImage();

		event EventHandler TextChanged;
		event EventHandler ImageChanged;
		event EventHandler EnableChanged;
	}

	public class ActionExecutionArgs : EventArgs {
		public IAppContext Context { get; set; }
		public IActionable Action { get; set; }
		public EventArgs Args { get; set; }
		public object Data { get; set; }
		public object ExecutionResult { get; set; }
	}

	public class ActionExecuteErrorArgs : EventArgs {

		public ActionExecuteErrorArgs(Exception ex) {
			this.Exception = ex;
			Handled = false;
		}

		public Exception Exception { get; private set; }
		public bool Handled { get; set; }
	}

	public static class ActionManagerExtension {

		public static IActionable getAction(this IActionManager actionManager, string name) {
			foreach (IActionable act in actionManager.Actions)
				if (act.Name.Equals(name))
					return act;
			return null;
		}
	}
}
